package com.beyondbit.hr.api.utils;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URL;
import java.nio.charset.Charset;

public class HttpUtils {

    public static Logger logger() {
        return LoggerFactory.getLogger(HttpUtils.class);
    }

    public static CloseableHttpClient httpClient() {
        return HttpClients.createSystem();
    }



    public static String jsonPostRaw(URL url, String body, Charset charset) throws Exception {
        try (CloseableHttpClient httpClient = httpClient()) {
            HttpPost httpPost = new HttpPost(url.toURI());
            Charset cs = charset != null ? charset : Charset.defaultCharset();
            byte[] data = body.getBytes(cs);
            HttpEntity entity = new ByteArrayEntity(data);
            httpPost.setEntity(entity);
            httpPost.setHeader(HttpHeaders.CONTENT_TYPE, String.format("application/json; charset=%s",cs.displayName()));

            CloseableHttpResponse response = httpClient.execute(httpPost);
            HttpEntity responseEntity = response.getEntity();
            byte[] rspBytes = EntityUtils.toByteArray(responseEntity);
            String rspMsg = new String(rspBytes,cs);
            if (response.getStatusLine().getStatusCode() > 400) {
                throw new  NonRollbackException(rspMsg);
            }else {
                return rspMsg;
            }

        } catch (Throwable e) {
            logger().error(ExceptionUtils.stackTraceMessage(e));
            throw e;
        }
    }

    public static <T> T jsonPost(URL url,Object req,Class<T> rspType)throws Exception{
        TypeFactory typeFactory = TypeFactory.defaultInstance();
        return jsonPost(url,req,typeFactory.constructType(rspType));
    }

    public static <T> T jsonPost(URL url, Object req, JavaType rspType)throws Exception{
        ObjectMapper objectMapper = JsonUtils.objectMapper();
        String json = objectMapper.writeValueAsString(req);
        Charset charset = Charset.forName("UTF-8");
        String rsp = jsonPostRaw(url,json,charset);
        return objectMapper.readValue(rsp,rspType);
    }
}
